package javaNIO1.charSets;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;

/**
 * Created with Intel IDEA.
 * 字符集： 编码
 *
 * @Auther: gjt
 * @Date: 2024/8/4 9:28
 */
public class CharSetss {
    public static void main(String[] args) {

        Charset cs = Charset.forName("UTF-8");
        CharBuffer zhongguo = CharBuffer.wrap("中国");
        ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

        // 在编码之前 检测该编码集合是否允许编码
        if (!cs.canEncode()) {
            System.out.println("该字符集不允许编码");
            return;
        }


        try {
            // 从字符集对象中创建字符编码器对象（作用就是把字符集合转成字节集合）它是一个状态转换引擎；字符进 字节出；
            // 每个编码器和一个CharSet 关联
            CharsetEncoder charsetEncoder = cs.newEncoder();
            // 重新设置编码器的状态； 清除以前的东西，新建的一般不会有以前的但是可以调用这个方法
            charsetEncoder.reset();

            // 使用编码器检测输入源 是否可以编码
            if(!charsetEncoder.canEncode(zhongguo)){
                System.out.println("输入源不能编码");
                return;
            }

            // false表示后面可能还有很多的字符，给定的CharBuffer 消耗字符，编码字节序列将被添加到提供的ByteBuffer中
            //最后一次调用encode  true表示提供的CharBuffer 可能包含额外的需要编码的字符或者空；这个样就能通知编码引擎后面没有输入了，允许它探测有缺陷的输入
            CoderResult encode = charsetEncoder.encode(zhongguo, buffer, false);


            // 来完成未完成的编码并输出所有剩下的字节，如果字节缓冲区没有足够的空间组要多次调用；当消耗了所有的输入时，当输出字节缓冲区满时，或者 当探测到编码错误时encode() 返回
            charsetEncoder.flush(buffer);



            // 返回原来的字符集对象备份的参考
            Charset charset = charsetEncoder.charset();

            // 返回表示编码集合的字符所需要的平均字节数
            float v = charsetEncoder.averageBytesPerChar();

            // 返回表示在集合中编码单个字符所需要的最大字节数  这个值乘以编码字符数量将得出最坏情况下缓冲区的大小
            float v1 = charsetEncoder.maxBytesPerChar();

            // 使用编码器 (编码时会抛出异常可能选择的字符集不合法等) 使用编码器的默认方式
            cs.encode(zhongguo);
            // 等价上边的；默认字节序列替换任意的未识别或无效输入字符
            cs.newEncoder().onMalformedInput(CodingErrorAction.REPLACE)
                    .onUnmappableCharacter(CodingErrorAction.REPLACE)
                    .encode(zhongguo);

            // 找回替换的字节序列，如果没有设置就返回的默认的
            byte[] replacement = charsetEncoder.replacement();

            // 我的替换字节序列
            String replacementString = new String("123");

            // 检测自己的替换字节序列是否有效
            if(!charsetEncoder.isLegalReplacement(replacementString.getBytes())){
                System.out.println("替换字节序列无效");
                return;
            }

            String replacements = new String("456");
            // 设置新的替换字节序列，
            charsetEncoder.replaceWith(replacements.getBytes());
        } catch (CharacterCodingException e) {
            throw new RuntimeException(e);
        }
    }
}
